// Copyright (c) 2020-present, INSPUR Co, Ltd. All rights reserved.
// This source code is licensed under Apache 2.0 License.

#pragma once

#include "pure_mem/key_index/abstract_tree.h"
#include "pure_mem/key_index/abstract_uk_index.h"
#include "pure_mem/key_index/tree_void_ref.h"
#include "pure_mem/thread_safe_dlink.h"

namespace rocksdb {

// UserKeyIndex class used to encapsulate ART tree operations.
class UserKeyIndex : public IUserKeyIndex {
public:
  UserKeyIndex(UserKeyIndexType type, ITreeVoidRef::RefType refType,
      Logger *log = nullptr);
  ~UserKeyIndex();

  // no allow copy.
  UserKeyIndex(const UserKeyIndex &) = delete;
  UserKeyIndex(UserKeyIndex &&t) = delete;
  UserKeyIndex &operator=(const UserKeyIndex &) = delete;
  UserKeyIndex &operator=(UserKeyIndex &&) = delete;

  // get userkey corresponeding TreeVoidRef object in ART tree,
  // if not exist new one object and put onto ART tree.
  ITreeVoidRef *getTreeVoidRef(const Slice &userKey, const VersionNode *node) override;
  // get one TreeVoidRef object whose key equal or greater userkey,
  // while no object match, return nullptr.
  ITreeVoidRef *getGETreeVoidRef(const Slice &userKey) override;
  ITreeVoidRef *getGLTreeVoidRef(const Slice &userKey) override;

  ITreeVoidRef *head() override { return treeVoidRef_dlink_->getHead(); }
  ITreeVoidRef *tail() override { return treeVoidRef_dlink_->getTail(); }

private:
  // TreeVoidRef object double link list. used for key range scan.
  ConcurrentDLink<ITreeVoidRef *> *treeVoidRef_dlink_;
  ITreeVoidRef::RefType refType_;
};
} // namespace rocksdb
